package lk.icta.core.entity;

import lk.icta.common.entity.*;

import javax.persistence.*;
import java.util.Date;
import java.util.List;

@Entity
@Table(schema = "ELAND_RAIL")
@NamedQueries({
        @NamedQuery(
                name = "getLandsByDistrictAndState",
                query = "SELECT l FROM LandRailway l WHERE l.district.id = :districtId AND l.state =:state"
        ),
        @NamedQuery(
                name = "getLandByFileNoByUser",
                query = "SELECT l FROM LandRailway l WHERE " +
                        "(1 = :ignoreDS AND l.landFileNumber = :fNo) OR " +
                        "(0 = :ignoreDS AND l.landFileNumber = :fNo AND  l.district IN (:DSList) AND (l.branch.id =:branchId)) OR " +
                        "(2 = :ignoreDS AND l.landFileNumber = :fNo AND (l.branch.id =:branchId )) "
        ),

        @NamedQuery(
                name = "getLandByFileNumberByUserAndState",
                query = "SELECT l FROM LandRailway l WHERE " +
                        "(1 = :ignoreDS AND l.landFileNumber = :fNo AND l.state in (:stateSet)) OR " +
                        "(0 = :ignoreDS AND l.landFileNumber = :fNo AND l.state in (:stateSet) AND  l.district IN (:DSList) AND (l.branch.id =:branchId)) OR " +
                        "(2 = :ignoreDS AND l.landFileNumber = :fNo AND l.state in (:stateSet) AND (l.branch.id =:branchId )) "
        ),
        @NamedQuery(
                name = "getLandByFileNo",
                query = "SELECT l FROM LandRailway l WHERE l.landFileNumber = :fNo"
        ),
        @NamedQuery(
            name = "getLandFileNoLike",
            query = "SELECT l FROM LandRailway l WHERE l.landFileNumber LIKE :fileNo"
        )


})
public class LandRailway extends BaseEntity {

    public enum State {
        ARCHIVED,   // 0 - state. Archived and can not be edited nor available for alienation

        REJECTED,   // 1 - State.
        DATA_ENTRY,   // 2 - State.
        PENDING,    // 3 - State.
        APPROVED // 4 - State.
    }

    public enum MigrationState {
        NONE,         // 0 - Non migrated record
        ACCESS_DB,    // 1 - Migrated form Acess DB
        EXCEL         // 2 - Migrated from Excel Sheets
    }

    @ManyToOne
    @JoinColumn(nullable = false)
    private District district;

    @ManyToOne
    @JoinColumn(nullable = false)
    private RailwayTrack railwayTrack;

    @ManyToOne
    @JoinColumn(nullable = false)
    private DistrictEngineerZone districtEngineerZone;

    @ManyToOne
    @JoinColumn(nullable = false)
    private IPWZone ipwZone;

    @ManyToOne
    @JoinColumn(nullable = true)
    private Branch branch;

    @ManyToOne
    @JoinColumn
    private RailwayProtectionZone railwayProtectionZone;

    @ManyToOne
    @JoinColumn
    private RailwayStation nearestRailwayStation;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn
    private LandLocation landLocation;

    @ManyToOne
    @JoinColumn(name = "geologicalType", nullable = true)
    private GeologicalType geologicalType;

    @Column(nullable = false)
    private String landFileNumber;

    @Column(nullable = true)
    private String village;

    @Column(nullable = true)
    private String planNumber;

    @Column(nullable = true)
    private String lotNumber;

    @Column(nullable = true)
    private String surveyor;

    @Column(nullable = true)
    @Temporal(value = TemporalType.DATE)
    private Date planDate;

    @Column(nullable = true)
    private double landExtent;

    @Column(nullable = true)
    private String northBoundary;

    @Column(nullable = true)
    private String northEastBoundary;

    @Column(nullable = true)
    private String eastBoundary;

    @Column(nullable = true)
    private String southEastBoundary;

    @Column(nullable = true)
    private String southBoundary;

    @Column(nullable = true)
    private String southWestBoundary;

    @Column(nullable = true)
    private String westBoundary;

    @Column(nullable = true)
    private String northWestBoundary;

    @ManyToOne
    @JoinColumn(name = "northBoundaryType", nullable = true)
    private BoundaryType northBoundaryType;

    @ManyToOne
    @JoinColumn(name = "northEastBoundaryType", nullable = true)
    private BoundaryType northEastBoundaryType;

    @ManyToOne
    @JoinColumn(name = "eastBoundaryType", nullable = true)
    private BoundaryType eastBoundaryType;

    @ManyToOne
    @JoinColumn(name = "southEastBoundaryType", nullable = true)
    private BoundaryType southEastBoundaryType;

    @ManyToOne
    @JoinColumn(name = "southBoundaryType", nullable = true)
    private BoundaryType southBoundaryType;

    @ManyToOne
    @JoinColumn(name = "southWestBoundaryType", nullable = true)
    private BoundaryType southWestBoundaryType;

    @ManyToOne
    @JoinColumn(name = "westBoundaryType", nullable = true)
    private BoundaryType westBoundaryType;

    @ManyToOne
    @JoinColumn(name = "northWestBoundaryType", nullable = true)
    private BoundaryType northWestBoundaryType;

    @Column(nullable = false)
    private State state;

    @Column(nullable = true, columnDefinition = "text")
    private String approvalNote;

    @Column(nullable = true, columnDefinition = "text")
    private String landVisitComment;

    @Column(nullable = true)
    private MigrationState migrationState;

    @Transient
    private List<Document> documentList;

    @Embedded
    private LifeCycleInfo lifeCycleInfo = new LifeCycleInfo();

    public String getVillage() {
        return village;
    }

    public void setVillage(String village) {
        this.village = village;
    }

    public String getPlanNumber() {
        return planNumber;
    }

    public void setPlanNumber(String planNumber) {
        this.planNumber = planNumber;
    }

    public String getLotNumber() {
        return lotNumber;
    }

    public void setLotNumber(String lotNumber) {
        this.lotNumber = lotNumber;
    }

    public double getLandExtent() {
        return landExtent;
    }

    public void setLandExtent(double landExtent) {
        this.landExtent = landExtent;
    }

    public GeologicalType getGeologicalType() {
        return geologicalType;
    }

    public void setGeologicalType(GeologicalType geologicalType) {
        this.geologicalType = geologicalType;
    }

    public String getApprovalNote() {
        return approvalNote;
    }

    public void setApprovalNote(String approvalNote) {
        this.approvalNote = approvalNote;
    }

    public List<Document> getDocumentList() {
        return documentList;
    }

    public void setDocumentList(List<Document> documentList) {
        this.documentList = documentList;
    }

    public LifeCycleInfo getLifeCycleInfo() {
        return lifeCycleInfo;
    }

    public void setLifeCycleInfo(LifeCycleInfo lifeCycleInfo) {
        this.lifeCycleInfo = lifeCycleInfo;
    }

    public String getSurveyor() {
        return surveyor;
    }

    public void setSurveyor(String surveyor) {
        this.surveyor = surveyor;
    }

    public Date getPlanDate() {
        return planDate;
    }

    public void setPlanDate(Date planDate) {
        this.planDate = planDate;
    }

    public String getLandVisitComment() {
        return landVisitComment;
    }

    public void setLandVisitComment(String landVisitComment) {
        this.landVisitComment = landVisitComment;
    }


    public BoundaryType getNorthBoundaryType() {
        return northBoundaryType;
    }

    public void setNorthBoundaryType(BoundaryType northBoundaryType) {
        this.northBoundaryType = northBoundaryType;
    }

    public BoundaryType getNorthEastBoundaryType() {
        return northEastBoundaryType;
    }

    public void setNorthEastBoundaryType(BoundaryType northEastBoundaryType) {
        this.northEastBoundaryType = northEastBoundaryType;
    }

    public BoundaryType getEastBoundaryType() {
        return eastBoundaryType;
    }

    public void setEastBoundaryType(BoundaryType eastBoundaryType) {
        this.eastBoundaryType = eastBoundaryType;
    }

    public BoundaryType getSouthEastBoundaryType() {
        return southEastBoundaryType;
    }

    public void setSouthEastBoundaryType(BoundaryType southEastBoundaryType) {
        this.southEastBoundaryType = southEastBoundaryType;
    }

    public BoundaryType getSouthBoundaryType() {
        return southBoundaryType;
    }

    public void setSouthBoundaryType(BoundaryType southBoundaryType) {
        this.southBoundaryType = southBoundaryType;
    }

    public BoundaryType getSouthWestBoundaryType() {
        return southWestBoundaryType;
    }

    public void setSouthWestBoundaryType(BoundaryType southWestBoundaryType) {
        this.southWestBoundaryType = southWestBoundaryType;
    }

    public BoundaryType getWestBoundaryType() {
        return westBoundaryType;
    }

    public void setWestBoundaryType(BoundaryType westBoundaryType) {
        this.westBoundaryType = westBoundaryType;
    }

    public BoundaryType getNorthWestBoundaryType() {
        return northWestBoundaryType;
    }

    public void setNorthWestBoundaryType(BoundaryType northWestBoundaryType) {
        this.northWestBoundaryType = northWestBoundaryType;
    }

    public String getNorthBoundary() {
        return northBoundary;
    }

    public void setNorthBoundary(String northBoundary) {
        this.northBoundary = northBoundary;
    }

    public String getNorthEastBoundary() {
        return northEastBoundary;
    }

    public void setNorthEastBoundary(String northEastBoundary) {
        this.northEastBoundary = northEastBoundary;
    }

    public String getEastBoundary() {
        return eastBoundary;
    }

    public void setEastBoundary(String eastBoundary) {
        this.eastBoundary = eastBoundary;
    }

    public String getSouthEastBoundary() {
        return southEastBoundary;
    }

    public void setSouthEastBoundary(String southEastBoundary) {
        this.southEastBoundary = southEastBoundary;
    }

    public String getSouthBoundary() {
        return southBoundary;
    }

    public void setSouthBoundary(String southBoundary) {
        this.southBoundary = southBoundary;
    }

    public String getSouthWestBoundary() {
        return southWestBoundary;
    }

    public void setSouthWestBoundary(String southWestBoundary) {
        this.southWestBoundary = southWestBoundary;
    }

    public String getWestBoundary() {
        return westBoundary;
    }

    public void setWestBoundary(String westBoundary) {
        this.westBoundary = westBoundary;
    }

    public String getNorthWestBoundary() {
        return northWestBoundary;
    }

    public void setNorthWestBoundary(String northWestBoundary) {
        this.northWestBoundary = northWestBoundary;
    }

    public District getDistrict() {
        return district;
    }

    public void setDistrict(District district) {
        this.district = district;
    }

    public RailwayTrack getRailwayTrack() {
        return railwayTrack;
    }

    public void setRailwayTrack(RailwayTrack railwayTrack) {
        this.railwayTrack = railwayTrack;
    }

    public DistrictEngineerZone getDistrictEngineerZone() {
        return districtEngineerZone;
    }

    public void setDistrictEngineerZone(DistrictEngineerZone districtEngineerZone) {
        this.districtEngineerZone = districtEngineerZone;
    }

    public IPWZone getIpwZone() {
        return ipwZone;
    }

    public void setIpwZone(IPWZone ipwZone) {
        this.ipwZone = ipwZone;
    }

    public RailwayProtectionZone getRailwayProtectionZone() {
        return railwayProtectionZone;
    }

    public void setRailwayProtectionZone(RailwayProtectionZone railwayProtectionZone) {
        this.railwayProtectionZone = railwayProtectionZone;
    }

    public RailwayStation getNearestRailwayStation() {
        return nearestRailwayStation;
    }

    public void setNearestRailwayStation(RailwayStation nearestRailwayStation) {
        this.nearestRailwayStation = nearestRailwayStation;
    }

    public LandLocation getLandLocation() {
        return landLocation;
    }

    public void setLandLocation(LandLocation landLocation) {
        this.landLocation = landLocation;
    }

    public String getLandFileNumber() {
        return landFileNumber;
    }

    public void setLandFileNumber(String landFileNumber) {
        this.landFileNumber = landFileNumber;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    public Branch getBranch() {
        return branch;
    }

    public void setBranch(Branch branch) {
        this.branch = branch;
    }

    public MigrationState getMigrationState() {
        return migrationState;
    }

    public void setMigrationState(MigrationState migrationState) {
        this.migrationState = migrationState;
    }
}
